/*
Copyright (C) 1996-1997 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
// mathlib.h

typedef float vec_t;
typedef vec_t vec3_t[3];
typedef vec_t vec5_t[5];

typedef	int	fixed4_t;
typedef	int	fixed8_t;
typedef	int	fixed16_t;

typedef float matrix_4x4[4][4];       // the standard 4x4 homogenous matrix

typedef float matrix_1x4[4];          // a 1x4 matrix or a row vector

#ifndef M_PI
#define M_PI		3.14159265358979323846	// matches value in gcc v2 math.h
#endif

struct mplane_s;
extern vec3_t vec3_origin;

#define NANMASK             (255 << 23)
#define	IS_NAN(x)           (((*(int *) & x) & NANMASK) == NANMASK)

#define	DIST_EPSILON	    (0.03125)
#define COLINEAR_EPSILON    (0.001)

#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
#define CrossProduct(a,b,c)((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0])
#define VectorClear(a){a[0]=vec3_origin[0];a[1]=vec3_origin[1];a[2]=vec3_origin[2];}
#define VectorCompare(a,b)(((a)[0]==(b)[0])&&((a)[1]==(b)[1])&&((a)[2]==(b)[2]))
#define VectorInverse(v)(v[0]=-v[0],v[1]=-v[1],v[2]=-v[2])
#define VectorMA(a, scale, b, c)((c)[0]=(a)[0]+(scale)*(b)[0],(c)[1]=(a)[1]+(scale)*(b)[1],(c)[2]=(a)[2]+(scale)*(b)[2])

float	anglemod (float a);
float	angledelta (float a);

void    VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out);
void    VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out);
void    VectorCopy (vec3_t in, vec3_t out);
void    VectorScale (vec3_t in, vec_t scale, vec3_t out);
void    VectorConstruct(float vec1, float vec2, float vec3, vec3_t out);

float	Length (vec3_t v);
float   Distance(const vec3_t v, const vec3_t v2);
float   Normalize (vec3_t inout);

void	MatrixAffineInverse (matrix_4x4  m, matrix_4x4 result);		// <AWE> added prototype.
void	Mat_Mul_1x4_4x4 (matrix_1x4 a, matrix_4x4 b,matrix_1x4 result);	// <AWE> added prototype.

void	VectorAngles (const vec3_t normal, vec3_t angles);
void	AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);

#define RAD2DEG( a ) ( ( (a) * 180.0f ) / M_PI )
#define DEG2RAD( a ) ( ( (a) * M_PI ) / 180.0F )

int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *p);

#define BOX_ON_PLANE_SIDE(emins, emaxs, p)	\
	(((p)->type < 3)?						\
	(										\
		((p)->dist <= (emins)[(p)->type])?	\
			1								\
		:									\
		(									\
			((p)->dist >= (emaxs)[(p)->type])?\
				2							\
			:								\
				3							\
		)									\
	)										\
	:										\
		BoxOnPlaneSide( (emins), (emaxs), (p)))
